From 455b57e028aff0bda9728a366018498f41a6cab2 Mon Sep 17 00:00:00 2001
From: "Miouyouyou (Myy)" <myy@miouyouyou.fr>
Date: Tue, 30 Oct 2018 22:44:54 +0100
Subject: [PATCH 1/2] mmc: Added a flag to disable cache flush during reset

The ASUS Chromebook suffer from 10 minutes long hang, when trying
to flush the cache of the eMMC, in order to recover from eMMC init
issues when booting the system.

A new flag "no-recovery-cache-flush" whose purpose is to disable
cache flush during recovery reset, has been added.

This work is adapted from @SolidHal work, which is available here :
https://github.com/SolidHal/PrawnOS/blob/develop-4.19/resources/BuildResources/patches-tested/kernel/Don-t-try-to-flush-cache-on-reset.patch

Signed-off-by: Miouyouyou (Myy) <myy@miouyouyou.fr>
---
 drivers/mmc/core/host.c  |  2 ++
 drivers/mmc/core/mmc.c   | 17 +++++++++++++----
 include/linux/mmc/host.h |  1 +
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c
index f57f5de54..4e49522f7 100644
--- a/drivers/mmc/core/host.c
+++ b/drivers/mmc/core/host.c
@@ -322,6 +322,8 @@ int mmc_of_parse(struct mmc_host *host)
 		host->caps2 |= MMC_CAP2_NO_SD;
 	if (device_property_read_bool(dev, "no-mmc"))
 		host->caps2 |= MMC_CAP2_NO_MMC;
+	if (device_property_read_bool(dev, "no-recovery-cache-flush"))
+		host->caps2 |= MMC_CAP2_NO_RECOVERY_CACHE_FLUSH;
 
 	/* Must be after "non-removable" check */
 	if (device_property_read_u32(dev, "fixed-emmc-driver-type", &drv_type) == 0) {
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
index bc1bd2c25..be2e3f359 100644
--- a/drivers/mmc/core/mmc.c
+++ b/drivers/mmc/core/mmc.c
@@ -2133,6 +2133,12 @@ static int mmc_runtime_resume(struct mmc_host *host)
 	return 0;
 }
 
+static inline int mmc_can_flush_during_recovery(
+	struct mmc_host *host)
+{
+	return (host->caps2 & MMC_CAP2_NO_RECOVERY_CACHE_FLUSH) == 0;
+}
+
 static int mmc_can_reset(struct mmc_card *card)
 {
 	u8 rst_n_function;
@@ -2147,11 +2153,14 @@ static int _mmc_hw_reset(struct mmc_host *host)
 {
 	struct mmc_card *card = host->card;
 
-	/*
-	 * In the case of recovery, we can't expect flushing the cache to work
-	 * always, but we have a go and ignore errors.
+	/* Using a "Cache flush" during recovery events seems...
+	 * "dubious" at best, and generate significant issues on
+	 * some platforms, like 10 minutes hang up, at worst.
+	 * I'm keeping this line because the old code did it but...
+	 * feel free to double check if that's needed at all.
 	 */
-	mmc_flush_cache(host->card);
+	if (mmc_can_flush_during_recovery(host))
+		mmc_flush_cache(host->card);
 
 	if ((host->caps & MMC_CAP_HW_RESET) && host->ops->hw_reset &&
 	     mmc_can_reset(card)) {
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
index beed7121c..31e670a8a 100644
--- a/include/linux/mmc/host.h
+++ b/include/linux/mmc/host.h
@@ -367,6 +367,7 @@ struct mmc_host {
 #define MMC_CAP2_CQE		(1 << 23)	/* Has eMMC command queue engine */
 #define MMC_CAP2_CQE_DCMD	(1 << 24)	/* CQE can issue a direct command */
 #define MMC_CAP2_AVOID_3_3V	(1 << 25)	/* Host must negotiate down from 3.3V */
+#define MMC_CAP2_NO_RECOVERY_CACHE_FLUSH	(1 << 26)	/* Do not flush the device cache when recovering */
 
 	int			fixed_drv_type;	/* fixed driver type for non-removable media */
 
-- 
2.16.4

